home *** CD-ROM | disk | FTP | other *** search
-
-
- /*
- ADDTOGRO.C Function PbAddToGroup: Adds a person entry to a group entry.
-
- INPUT: Phonebook structure, and the record id's of the person and group
- entries.
-
- OUTPUT: If successful, adds the person to the group's members list, and the
- group to the person's members list. If the new member changes the
- group's HardwareType, that field is changed.
- */
-
- #include <stdio.h>
- #include <malloc.h>
- #include <phonebk.h>
-
- int pascal PbAddToGroup(PB *pb, int GroupID, int MemberID)
- {
- int retval = FAIL; /* default, if anything goes wrong */
- PBE *group = NULL,
- *member = NULL;
- LONGWORD group_offset,
- member_offset;
- int new_free_bytes;
- int buffed_rids;
-
- int i,
- writ, /* for return value of fwrite() */
- filenum;
- int temperrno = 0; /* for saving aside Pberrno */
-
- Pberrno = 0; /* Initially, always reset */
-
- /* First, check params */
- if (pb == NULL) {
- Pberrno = INVALIDPARAMETER;
- return(NULL);
- }
- if ((GroupID < 0) ||
- (GroupID > 999)) {
- Pberrno = INVALIDPARAMETER;
- return(NULL);
- }
- if ((MemberID < 0) ||
- (MemberID > 999)) {
- Pberrno = INVALIDPARAMETER;
- return(NULL);
- }
-
- /* First, fetch the entries */
- if (!(group = PbGetEntry(pb, NULL, NULL, GroupID))) {
- goto getout; /* PbGetEntry sets Pberrno */
- }
- if (!(member = PbGetEntry(pb, NULL, NULL, MemberID))) {
- goto getout;
- }
-
- /* A few consistency checks */
- if (member->type != PERSONENTRY) {
- Pberrno = GROUPCANTBEMEMBER;
- goto getout;
- }
-
- if (group->type != GROUPENTRY) {
- Pberrno = PERSONCANTHAVEMEMBER;
- goto getout;
- }
-
- /* Check that the group doesn't already have the person as a member */
- for (i=0; i<group->members; i++) {
- if (group->MemberList[i] == MemberID) {
- break;
- }
- }
- if (i != group->members) {
- Pberrno = ENTRYALREADYMEMBER;
- goto getout;
- }
-
- /* Check that operation will not put phonebook's 'unused bytes' over limit */
- if (new_free_bytes = (pb->header.FreeBytes +
- group->length +
- member->length) > MAXUNUSEDBYTES) {
- Pberrno = TOOMANYFREEBYTES;
- goto getout;
- }
-
- /* Update fields of both entries */
- group->MemberList = (int *)realloc(group->MemberList,
- (group->members + 1) * sizeof(int));
- group->MemberList[group->members++] = MemberID;
- group->length += sizeof(int);
- member->MemberList = (int *)realloc(member->MemberList,
- (member->members + 1) * sizeof(int));
- member->MemberList[member->members++] = GroupID;
- member->length += sizeof(int);
-
- /* Set or change the hardware type of the group as appropriate */
- if (group->members == 1) { /* we're adding the first member */
- group->HardwareType = member->HardwareType;
- }
- else if ((group->HardwareType == HASCCC) &&
- (member->HardwareType == FAXONLY)) {
- group->HardwareType = FAXONLY;
- }
-
- /* Find out new offsets for the entries, in case the write is successful */
- filenum = fileno(pb->fp);
- if ((member_offset = filelength(filenum)) == -1L) {
- Pberrno = FILELENGTHERROR;
- goto getout;
- }
- group_offset = member_offset + member->length;
-
- /* Write the person entry to end of the file, quitting if error occurs */
- if (fseek(pb->fp, 0L, SEEK_END)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
-
- /* First, write the fixed part... */
- writ = fwrite(member, sizeof(PBEFIXED), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* ... then each of the optional fields, INCLUDING their NULL terminator... */
- for (i=0; i<pb->header.fields; i++) {
- writ = fwrite(member->fields[i], strlen(member->fields[i]) + 1, 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
- }
-
- /* ... and finally the membership list */
- writ = fwrite(member->MemberList,
- sizeof(int),
- member->members,
- pb->fp);
- if (writ != member->members) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* And write the group, too: first the fixed part, ... */
- writ = fwrite(group, sizeof(PBEFIXED), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* ...then the membership list */
- writ = fwrite(group->MemberList,
- sizeof(int),
- group->members,
- pb->fp);
- if (writ != group->members) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* If we got here, can update record ID's offsets and other pb fields*/
-
- /* If the Offset buffer is being used, check there for the id's */
- if (pb->OBuffer) {
- buffed_rids = pb->OBufferSize/sizeof(LONGWORD);
-
- /* If the id's are in the buffer, update them there */
- if ((MemberID >= pb->FirstOBufferRID) &&
- (MemberID < pb->FirstOBufferRID + buffed_rids)) {
- pb->OBuffer[MemberID - pb->FirstOBufferRID] = member_offset;
- }
- if ((GroupID >= pb->FirstOBufferRID) &&
- (GroupID < pb->FirstOBufferRID + buffed_rids)) {
- pb->OBuffer[GroupID - pb->FirstOBufferRID] = group_offset;
- }
- }
-
- /* And finally do the actual writes to the file */
- if (fseek(pb->fp, 160L + MemberID * sizeof(LONGWORD), SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&member_offset, sizeof(LONGWORD), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
- if (fseek(pb->fp, 160L + GroupID * sizeof(LONGWORD), SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&group_offset, sizeof(LONGWORD), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* And now set the FreeBytes phonebook field */
- pb->header.FreeBytes = new_free_bytes;
- if (fseek(pb->fp, 6L, SEEK_SET)) {
- Pberrno = FSEEKERROR;
- goto getout;
- }
- writ = fwrite(&pb->header.FreeBytes, sizeof(int), 1, pb->fp);
- if (writ != 1) {
- Pberrno = CANTWRITE;
- goto getout;
- }
-
- /* If we got all the way to here, all went well! */
- retval = SUCCESS;
-
- getout:
- if (Pberrno) {
- temperrno = Pberrno;
- }
- if (group) {
- PbFreePBE(pb, group);
- }
- if (member) {
- PbFreePBE(pb, member);
- }
- if (temperrno) {
- Pberrno = temperrno;
- }
- return(retval);
- }